// 1.promise 是一个类 天生的，类中需要传入一个executor 执行器，默认会立即执行
// 2.promise内部会提供两个方法，可以更改promise的状态 3个状态太：等待态 成功态 失败态
// resolve 触发成功（成功的内容） reject触发失败（失败的原因）undefined
// 如果一旦promise成功了就不能失败， 失败的情况reject， 抛出异常也不会有成功态
// 每个promise实例都要有一个then的方法，分别是成功的回调和失败的回调

const PENDING = 'PENDING'
const RESOLVE = 'RESOLVE' // 成功
const REJECT = 'REJECT'  // 失败
class Promise{
  constructor(executor) { // 宏变量
    this.status = PENDING // 默认是等待态
    this.value = undefined // 成功的原因
    this.reason = undefined // 失败的原因
    // 专门存放成功的回调函数
    this.onResolvedCallbacks = []
    // 专门存放失败的回调函数
    this.onRejectedCallbacks = []
    // 保证只有状态是等待态的时候， 才能改状态
    let resolve = (value) => {
      if(this.status == PENDING) {
        this.value = value
        this.status = RESOLVE
      }
      this.onResolvedCallbacks.forEach(fn => fn())
    }
    let reject = (reason) => {
      if(this.status == PENDING) {
        this.reason = reason
        this.status = REJECT
      }
      this.onRejectedCallbacks.forEach(fn => fn())
    }
    // 执行executor 传入成功和失败
    try {
      executor(resolve, reject)
    } catch (e) {
      console.log('catch---')
      console.log(e)
      reject(e) // 如果内部出错直接将err手动调用reject方法向下传递
    }
  }

  then(onfulfilled, onrejected){
    if(this.status === RESOLVE) {
      onfulfilled(this.value)
    }
    if(this.status === REJECT) {
      onrejected(this.reason)
    }
    if(this.status === PENDING) { 
      // 这时候 executor 是肯定有异步逻辑的
      this.onResolvedCallbacks.push(() => {
        // TODO... 切片编程
        onfulfilled(this.value)
      })

      this.onRejectedCallbacks.push(() => {
        onrejected(this.reason)
      })
    }
  }
}

module.exports = Promise